home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Offscreen.c
-
- Contains: QuickTime 3.0 Offscreen sample application.
-
- Written by: Scott Kuechle
- based on MDIPlayer code by Brian S. Friedkin
-
- Copyright: © 1998 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 5/18/98 rtm minor tweaks to GetBitDepthOfBitmap and DrawBackgroundBitmap to get this code
- working with the Metrowerks compiler
- <1> 4/24/98 srk first file; revised to personal coding style
-
-
- NOTES:
-
-
- TO DO:
-
- */
-
-
- #include "Application.h"
- #include "QTCode.h"
-
-
- long FAR PASCAL FrameWndProc (HWND, UINT, UINT, LONG) ;
- long FAR PASCAL MovieWndProc (HWND, UINT, UINT, LONG) ;
- BOOL DoOpenMovie();
- int DoIdleMenus(HWND hWnd, HMENU hMenu);
- static void DoCut(HWND);
- static void DoCopy(HWND);
- static void DoPaste(HWND);
- static void DoClear(HWND);
- static void DoUndo(HWND);
- static void DoAbout(void);
- HPALETTE DoCreatePaletteFromBitMap(HMODULE appInstance, WORD bitMapID);
- void SetMovieFrameTimeValue(Movie theMovie, TimeValue thisPoint);
- WORD GetBitDepthOfBitmap(HMODULE appInstance, WORD bitMapID);
- void GetRBGColorsFromBitmap(HDC hDC, HANDLE hInst, WORD bitMapID, LPRGBQUAD *srcRgbQuadArray, HPALETTE *hPalette);
- void DoEraseRect(HDC hDC, RECT *theRect);
- int GetLineHeight(HDC hDC);
- void DrawMovieAndBackground(HGLOBAL hWinStorage, HDC hDC, HWND hwnd);
-
-
- /* globals for this module */
- HANDLE ghInst = NULL;
- HWND ghWndFrame = NULL;
- HWND ghWndMDIClient = NULL;
- BOOL gWeAreSizingWindow = 0;
- BOOL gWeAreCreatingWindow = 0;
- int gOpenMovieCount = 0;
- char gAppName[20];
- char gChildName[20];
- LPRGBQUAD gSrcRgbQuadArray = NULL; /* rbg color values for our window background bitmap */
- HPALETTE gHBackgroundPalette = NULL; /* color palette for our window background */
- HANDLE ghBkgrndBitMap = NULL; /* bitmap we paint on the background of our client windows */
-
- /* ---------------------------------------------------------------- */
- /* */
- /* WinMain() */
- /* */
- /* */
- /* The main function for this application */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpszCmdLine, int nCmdShow)
- {
- HANDLE hAccel ;
- HWND hwndFrame;
- MSG msg ;
- WNDCLASSEX wc;
- BOOL success;
-
- ghInst = hInstance ;
-
- if (!hPrevInstance)
- {
- LoadString(hInstance, IDS_APPNAME, gAppName, sizeof(gAppName));
-
- // Register the frame window class
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC)FrameWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPICON));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wc.lpszMenuName = gAppName;
- wc.lpszClassName = gAppName;
- wc.hIconSm = LoadImage(hInstance,
- MAKEINTRESOURCE(IDI_APPICON),
- IMAGE_ICON,
- 16, 16,
- 0);
- if (!RegisterClassEx(&wc))
- {
- if (!RegisterClass((LPWNDCLASS)&wc.style))
- return FALSE;
- }
-
- LoadString(hInstance, IDS_MDICHILD, gChildName, sizeof(gChildName));
-
- // Register the Movie child window class
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC)MovieWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CHILDICON));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = NULL /* we want to handle erasing of the background ourselves */;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = gChildName;
- wc.hIconSm = LoadImage(hInstance,
- MAKEINTRESOURCE(IDI_CHILDICON),
- IMAGE_ICON,
- 16, 16,
- 0);
- if (!RegisterClassEx(&wc))
- {
- if (!RegisterClass((LPWNDCLASS)&wc.style))
- return FALSE;
- }
- }
-
- // Load accelerators
- hAccel = LoadAccelerators (hInstance, gAppName);
-
- // Create the main frame window
- ghWndFrame = hwndFrame = CreateWindow (gAppName, gAppName,
- WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL) ;
-
- /* get background bitmap for use with our client windows */
- ghBkgrndBitMap = LoadResource(ghInst, FindResource(ghInst, MAKEINTRESOURCE(IDB_BITMAP2), RT_BITMAP) );
-
- /* Show the window */
- ShowWindow(hwndFrame, nCmdShow);
- UpdateWindow(hwndFrame);
-
- /* Initialize QuickTime */
- success = QTCode_DoQTInit();
- if (success)
- {
- /* Process messages */
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (!TranslateMDISysAccel(ghWndMDIClient, &msg))
- if (!TranslateAccelerator(hwndFrame, hAccel, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- }
- else
- {
- MessageBox(hwndFrame, "Quicktime 3.0 not available", "", MB_OK);
- }
-
- /* QuickTime clean up */
- QTCode_QTCleanUp();
-
- return msg.wParam;
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* FrameWndProc() */
- /* */
- /* */
- /* The window procedure for the MDI frame window */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- long FAR PASCAL FrameWndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
- {
- HWND hwndChild ;
-
- switch (message)
- {
- case WM_CREATE: // Create the client window
- {
- CLIENTCREATESTRUCT ccs = {0};
-
- ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), WINDOWMENU);
- ccs.idFirstChild = IDM_WINDOWCHILD;
-
- // Create the MDI client filling the client area
- ghWndMDIClient = CreateWindow("mdiclient",
- NULL,
- WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL |
- WS_HSCROLL,
- 0, 0, 0, 0,
- hwnd,
- (HMENU)0xCAC,
- ghInst,
- (LPVOID)&ccs);
-
- ShowWindow(ghWndMDIClient, SW_SHOW);
- }
- return 0 ;
-
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDM_FILEOPEN:
- DoOpenMovie();
- return 0 ;
-
- case IDM_FILECLOSE:
- hwndChild = (HWND)SendMessage(ghWndMDIClient, WM_MDIGETACTIVE, 0, 0L) ;
- if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0L))
- {
- SendMessage (ghWndMDIClient, WM_MDIDESTROY, (WPARAM)hwndChild, 0L) ;
- }
- return 0 ;
-
- case IDM_EXIT:
- SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
- return 0 ;
-
- case IDM_WINDOWTILE:
- SendMessage (ghWndMDIClient, WM_MDITILE, 0, 0L) ;
- return 0 ;
-
- case IDM_WINDOWCASCADE:
- SendMessage (ghWndMDIClient, WM_MDICASCADE, 0, 0L) ;
- return 0 ;
-
- case IDM_WINDOWICONS:
- SendMessage (ghWndMDIClient, WM_MDIICONARRANGE, 0, 0L) ;
- return 0 ;
-
- case IDM_WINDOWCLOSEALL:
- {
- HWND hwndT;
-
- while (hwndT = GetWindow(ghWndMDIClient, GW_CHILD))
- {
- // Skip the icon and title windows
- while (hwndT && GetWindow(hwndT, GW_OWNER))
- hwndT = GetWindow(hwndT, GW_HWNDNEXT);
-
- if (!hwndT) break;
-
- SendMessage(ghWndMDIClient, WM_MDIDESTROY, (WPARAM)hwndT, 0L);
- }
- }
- return 0;
-
- case IDM_ABOUT:
- DoAbout();
- return 0;
-
- default: // Pass to active child
- hwndChild = (HWND)SendMessage (ghWndMDIClient, WM_MDIGETACTIVE, 0, 0L) ;
- if (IsWindow (ghWndMDIClient))
- SendMessage (hwndChild, WM_COMMAND, wParam, lParam) ;
-
- break ; // and then to DefFrameProc
- }
- break ;
-
- case WM_INITMENU:
- if (GetMenu(hwnd) == (HMENU)wParam)
- return DoIdleMenus((HWND)SendMessage(ghWndMDIClient, WM_MDIGETACTIVE, 0, 0), (HMENU)wParam);
- return 1;
-
- case WM_DESTROY :
- PostQuitMessage (0) ;
- return 0 ;
- }
-
- return DefFrameProc (hwnd, ghWndMDIClient, message, wParam, lParam) ;
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* MovieWndProc() */
- /* */
- /* */
- /* The window procedure for our movie window */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- long FAR PASCAL MovieWndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
- {
- HGLOBAL hWinStorage = NULL;
- ChildWindowPtr childWinPtr = NULL;
- MSG msg = {0};
-
-
- hWinStorage = (HGLOBAL)GetWindowLong(hwnd, GWL_USERDATA);
-
- switch (message)
- {
- case WM_CREATE:
- {
- GrafPtr gp;
-
- /* Tuck away some private storage */
- hWinStorage = GlobalAlloc(GMEM_MOVEABLE + GMEM_ZEROINIT, sizeof(ChildWindowRecord));
- SetWindowLong(hwnd, GWL_USERDATA, (LPARAM)hWinStorage);
-
- /* Associate a GrafPort with this window */
- gp = QTCode_DoCreatePortAssociation(hwnd, NULL, 0);
-
- }
- return 0;
-
- case WM_GETMINMAXINFO:
- {
- if (hWinStorage != NULL)
- {
- childWinPtr = (ChildWindowPtr)GlobalLock(hWinStorage);
- if (childWinPtr != NULL)
- {
- LPMINMAXINFO lpmmi;
-
- lpmmi = (LPMINMAXINFO) lParam;
- /* we restrict the grow size of our window */
- lpmmi->ptMaxSize.x = childWinPtr->maxWindowWidth;
- lpmmi->ptMaxSize.y = childWinPtr->maxWindowHeight;
- lpmmi->ptMaxTrackSize.x = childWinPtr->maxWindowWidth;
- lpmmi->ptMaxTrackSize.y = childWinPtr->maxWindowHeight;
-
- GlobalUnlock(hWinStorage);
- }
- }
- }
- return 0;
-
- case WM_PAINT:
- {
- PAINTSTRUCT lPaint;
- HDC hDC;
-
- hDC = BeginPaint(hwnd, &lPaint);
- if (hDC != NULL)
- {
- DrawMovieAndBackground(hWinStorage, hDC, hwnd);
- }
- EndPaint(hwnd, &lPaint);
- }
- return 0;
-
- case WM_WINDOWPOSCHANGING:
- // Don't show the window until we have created a movie and therefore
- // can properly size the window to contain the movie.
- if (gWeAreCreatingWindow)
- {
- WINDOWPOS *lpWindowPos = (WINDOWPOS*)lParam;
- lpWindowPos->flags &= ~SWP_SHOWWINDOW;
- return 0;
- }
-
-
- return 0;
-
- case WM_KEYDOWN:
- if (wParam == VK_RETURN) /* return key was pressed */
- {
- HDC hDC = NULL;
- OSType mediaType = VideoMediaType;
-
- if (hWinStorage != NULL)
- {
- childWinPtr = (ChildWindowPtr)GlobalLock(hWinStorage);
- if (childWinPtr != NULL)
- {
- /* move to next interesting movie time to display */
- childWinPtr->currentTime =
- QTCode_DoGetMovieNextInterestingTime(childWinPtr->currentTime, childWinPtr->movie,
- VideoMediaType);
- GlobalUnlock(hWinStorage);
-
- hDC = GetDC(hwnd);
- if (hDC != NULL)
- {
- DrawMovieAndBackground(hWinStorage, hDC, hwnd);
- ReleaseDC(hwnd, hDC);
- }
- }
- }
- }
-
- return 0;
-
- case WM_SIZE:
- {
- if (hWinStorage != NULL)
- {
- childWinPtr = (ChildWindowPtr)GlobalLock(hWinStorage);
- if (childWinPtr != NULL)
- {
- if (childWinPtr->movie)
- {
- QTCode_PositionMovieRectInClientWindow(childWinPtr->movie, hwnd);
- }
- GlobalUnlock(hWinStorage);
- }
- }
- }
- return 0;
-
- case WM_ERASEBKGND:
- {
- /* we don't want the background erased when the window is
- re-sized, so we'll trap calls here for the WM_ERASEBKGND
- event */
- }
- return (1); /* tell GDI we've handled erasing ourselves */
-
- case WM_COMMAND:
- {
- switch(LOWORD(wParam)) // Undo, Cut, Copy, Paste and Clear
- {
- case IDM_EDITUNDO:
- DoUndo(hwnd);
- break;
-
- case IDM_EDITCUT:
- DoCut(hwnd);
- break;
-
- case IDM_EDITCOPY:
- DoCopy(hwnd);
- break;
-
- case IDM_EDITPASTE:
- DoPaste(hwnd);
- break;
-
- case IDM_EDITCLEAR:
- DoClear(hwnd);
- break;
- }
- }
- break;
-
- case WM_DESTROY:
- {
- if (hWinStorage != NULL)
- {
- childWinPtr = (ChildWindowPtr)GlobalLock(hWinStorage);
- if (childWinPtr != NULL)
- {
- /* One less movie open */
- --gOpenMovieCount;
-
- QTCode_DisposeMovieAndController(childWinPtr->movie, childWinPtr->refNum);
- /* Destroy the port association */
- QTCode_DoDestroyPortAssociation(hwnd);
- /* clean up offscreen GWorld */
- QTCode_DoDestroyOffscreen(childWinPtr->offscreenGWorld, childWinPtr->hBitmap);
-
- SetWindowLong(hwnd, GWL_USERDATA, 0);
- GlobalUnlock(hWinStorage);
- GlobalFree((HGLOBAL)GetWindowLong(hwnd, GWL_USERDATA));
- }
- }
- }
- return 0;
- }
-
- return DefMDIChildProc (hwnd, message, wParam, lParam);
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoOpenMovie() */
- /* */
- /* */
- /* Code to open a given movie and prepare it for display in a */
- /* window */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- BOOL DoOpenMovie()
- {
- DWORD dwVersion;
- short len;
- char szPathName[256], szFileName[256];
- HWND hwndChild = 0;
- OPENFILENAME ofn = {0};
- HDC hDC;
- HGLOBAL hWinStorage = NULL;
- OSErr err;
- Movie movie = NULL;
- short movieRefNum;
- short movieResId;
- int movWidth, movHeight;
-
- // Present the dialog...
- *szPathName = 0;
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = ghWndFrame;
- ofn.lpstrFile = (LPSTR)szPathName;
- ofn.nMaxFile = sizeof(szPathName);
- ofn.lpstrFilter = "QuickTime Movies (*.mov) \0 *.mov\0All Files (*.*) \0 *.*\0";
- ofn.nFilterIndex = 1;
- ofn.lpstrInitialDir = NULL;
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
- if (!GetOpenFileName(&ofn)) goto bail;
-
- err = QTCode_NewMovieFromWinPathname(szPathName, /* c-string path to movie */
- &movie, /* Movie returned here */
- &movieRefNum, /* Movie RefNum returned here */
- &movieResId); /* Movie Resource ID returned here */
- if (err == noErr)
- {
- Rect movieBounds;
-
- GetMovieBox(movie, &movieBounds);
- movWidth = RECT_WIDTH(movieBounds);
- movHeight = RECT_HEIGHT(movieBounds);
- }
- // Create the child movie window
- dwVersion = GetVersion();
- gWeAreCreatingWindow = TRUE;
- if ((dwVersion < 0x80000000) || (LOBYTE(LOWORD(dwVersion)) < 4))
- {
- // This is Windows NT or Win32s, so use the WM_MDICREATE message
- MDICREATESTRUCT mcs;
-
- mcs.szClass = gChildName;
- mcs.szTitle = szFileName;
- mcs.hOwner = ghInst;
- mcs.x = CW_USEDEFAULT;
- mcs.y = CW_USEDEFAULT;
- mcs.cx = movWidth + kWinSpacer; /* set an appropriate width for our movie window */
- mcs.cy = movHeight + kWinSpacer; /* set an appropriate height for our movie window */
- mcs.style = 0;
- mcs.lParam = 0;
-
- hwndChild = (HWND) SendMessage(ghWndMDIClient,
- WM_MDICREATE,
- 0,
- (LPARAM)(LPMDICREATESTRUCT) &mcs);
- }
- else
- {
- // This method will only work with Windows 95, not Windows NT or Win32s
- hwndChild = CreateWindowEx(WS_EX_MDICHILD,
- gChildName,
- szFileName,
- 0,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- movWidth + kWinSpacer, /* set an appropriate width for our movie window */
- movHeight + kWinSpacer, /* set an appropriate height for our movie window */
- ghWndMDIClient,
- NULL,
- ghInst,
- 0);
- }
- gWeAreCreatingWindow = FALSE;
- if (!hwndChild) goto bail;
-
- // Set the window title to the movie filename
- len = strlen(szPathName);
- while (len--)
- {
- char c = szPathName[len];
- if (c == 0x5c || c == '/')
- {
- strcpy(szFileName, &szPathName[len+1]);
- break;
- }
- }
- SetWindowText(hwndChild, szFileName);
-
- // Store movie info in private window record
- hWinStorage = (HGLOBAL)GetWindowLong(hwndChild, GWL_USERDATA);
- if (hWinStorage != NULL)
- {
- ChildWindowPtr childWinPtr = NULL;
-
- childWinPtr = (ChildWindowPtr)GlobalLock(hWinStorage);
- if (childWinPtr != NULL)
- {
-
- childWinPtr->ghInst = ghInst;
-
- if (movie != NULL)
- {
- childWinPtr->movie = movie;
- childWinPtr->refNum = movieRefNum;
- childWinPtr->hBkgrndBitmap = ghBkgrndBitMap;
- childWinPtr->maxWindowWidth = movWidth + kWinSpacer;
- childWinPtr->maxWindowHeight = movHeight + kWinSpacer;
-
-
- QTCode_PositionMovieRectInClientWindow(childWinPtr->movie, hwndChild);
- err = QTCode_GetStartPointOfFirstVideoSample(childWinPtr->movie, &childWinPtr->currentTime);
- }
-
-
- hDC = GetDC(hwndChild);
- if (hDC != NULL)
- {
- WORD bitDepthDC;
- RECT windowRect;
- QDErr err;
-
- GetRBGColorsFromBitmap( hDC,
- ghInst,
- IDB_BITMAP2, /* ID of background bitmap we want to use */
- &childWinPtr->srcRgbQuadArray, /* on return, a pointer to a rgbquad
- structure for this bitmap */
- &childWinPtr->hBackgroundPalette); /* if bitmap bit depth <= 8, a custom palette */
- bitDepthDC = GetDCBitDepth(hDC);
- GetWindowRect(hwndChild, &windowRect);
- childWinPtr->hBitmap = DoCreateDIBSection(hDC, /* the device context for this HWND */
- childWinPtr->srcRgbQuadArray, /* pointer to RGBQUAD array to use when creating
- DIB - NULL if bit depth > 8 */
- bitDepthDC, /* screen depth setting */
- RECT_WIDTH(windowRect), /* window width */
- RECT_HEIGHT(windowRect) /* window height */
- );
- childWinPtr->hMemDC = DoCreateMemoryDC(hwndChild);
- SelectObject(childWinPtr->hMemDC, childWinPtr->hBitmap);
- err = QTCode_CreateOffscreen(&childWinPtr->offscreenGWorld,
- NULL,
- NULL,
- 0,
- childWinPtr->hBitmap,/* a pointer to a valid bitmap or NULL */
- childWinPtr->hMemDC); /* a pointer to a valid device context or NULL */
- QTCode_SetMovieGWorld(childWinPtr->movie, childWinPtr->offscreenGWorld);
-
- ReleaseDC(hwndChild, hDC);
- }
-
- GlobalUnlock(hWinStorage);
- }
- }
- SetWindowLong(hwndChild, GWL_USERDATA, (LPARAM)hWinStorage);
-
- // Show the window
- ShowWindow(hwndChild, SW_SHOW);
- UpdateWindow(hwndChild);
- SetFocus(hwndChild);
-
- // One more window has been opened
- gOpenMovieCount += 1;
-
- return TRUE;
-
- bail:
- if (hwndChild) SendMessage(ghWndMDIClient, WM_MDIDESTROY, (WPARAM)hwndChild, 0L);
-
- return FALSE;
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DrawMovieAndBackground() */
- /* */
- /* */
- /* Code to display a movie and background image in a given */
- /* window */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void DrawMovieAndBackground(HGLOBAL hWinStorage, HDC hDC, HWND hwnd)
- {
- HPALETTE previousPalette = NULL;
- ChildWindowPtr childWinPtr;
-
- if ((childWinPtr = (ChildWindowPtr)GlobalLock(hWinStorage)) != NULL)
- {
- RECT clientRect, windowRect;
- Rect movieBounds;
-
- previousPalette = UseCustomPalette(hDC, childWinPtr->hBackgroundPalette);
-
- GetClientRect(hwnd, &clientRect);
- GetWindowRect(hwnd, &windowRect);
-
- DrawBackgroundBitmap(childWinPtr->hMemDC, hwnd, childWinPtr->hBkgrndBitmap, &clientRect);
- DrawHelpMessage(childWinPtr->hMemDC, hwnd);
-
- GetMovieBox(childWinPtr->movie, &movieBounds);
- DoDrawFrameInfo(childWinPtr->hMemDC, hwnd, &movieBounds, childWinPtr->currentTime);
-
- SetMovieTimeValue(childWinPtr->movie, childWinPtr->currentTime);
- QTCode_ForceMovieRedraw(childWinPtr->movie);
-
- /* copy our memory DC image to the display DC */
- BitBlt(hDC, 0, 0, RECT_WIDTH(windowRect), RECT_HEIGHT(windowRect), childWinPtr->hMemDC,
- 0, 0, SRCCOPY);
-
- GlobalUnlock(hWinStorage);
- }
-
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoCut() */
- /* */
- /* */
- /* Handles clipboard "cut" operations */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static void DoCut(HWND hwnd)
- {
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoCopy() */
- /* */
- /* */
- /* Handles clipboard "copy" operations */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static void DoCopy(HWND hwnd)
- {
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoPaste() */
- /* */
- /* */
- /* Handles clipboard "paste" operations */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static void DoPaste(HWND hwnd)
- {
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoClear() */
- /* */
- /* */
- /* Handles clipboard "clear" operations */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static void DoClear(HWND hwnd)
- {
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoUndo() */
- /* */
- /* */
- /* Handles clipboard "undo" operations */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static void DoUndo(HWND hwnd)
- {
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoIdleMenus() */
- /* */
- /* */
- /* Enable the close item if there are any movie windows opened */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- int DoIdleMenus(HWND hWnd, HMENU hMenu)
- {
- /* Enable the close item if there are any movie windows opened */
- EnableMenuItem(hMenu, IDM_FILECLOSE, (gOpenMovieCount) ? MF_ENABLED : MF_GRAYED);
-
- return 0;
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DialogProc() */
- /* */
- /* */
- /* Callback for our dialog box */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static LRESULT CALLBACK DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- EndDialog(hDlg, IDOK);
- break;
- }
- break;
- }
-
- return 0;
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoAbout() */
- /* */
- /* */
- /* Displays a dialog box with information about our program */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- static void DoAbout()
- {
- DialogBox(ghInst, MAKEINTRESOURCE(IDD_ABOUT), ghWndFrame, (DLGPROC)DialogProc);
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DrawBackgroundBitmap() */
- /* */
- /* */
- /* Sets the pixels in the target device context to those from */
- /* a given DIB */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void DrawBackgroundBitmap( HDC hDC,
- HWND hwnd,
- HANDLE hBitMap,
- RECT *updateRect)
- {
- if ((hBitMap != NULL) && (hDC != NULL) && (hwnd != NULL))
- {
- LPBITMAPINFO lpBi;
- LPTSTR lpBits;
- int x, y, width, height;
- int success = FALSE;
- RECT clientRect;
- int childHeight, childWidth;
-
- GetClientRect(hwnd, &clientRect);
- childWidth = RECT_WIDTH(clientRect);
- childHeight = RECT_HEIGHT(clientRect);
-
- lpBi = (LPBITMAPINFO)LockResource(hBitMap);
-
- lpBits = (LPSTR)lpBi;
- lpBits += lpBi->bmiHeader.biSize + ((1 << lpBi->bmiHeader.biBitCount) * sizeof(RGBQUAD));
- width = lpBi->bmiHeader.biWidth;
- height = lpBi->bmiHeader.biHeight;
-
- for (y = 0; y <= childHeight; y += lpBi->bmiHeader.biHeight)
- {
- for (x = 0; x <= childWidth; x += lpBi->bmiHeader.biWidth)
- {
- BOOL intersectRect = FALSE;
- RECT bitMapRect;
- RECT destRect;
-
- SetRect(&bitMapRect, x, y, x+lpBi->bmiHeader.biWidth, y+lpBi->bmiHeader.biHeight);
-
- intersectRect = IntersectRect( &destRect, // address of structure for intersection
- updateRect, // address of structure with first rectangle
- &bitMapRect // address of structure with second rectangle
- );
- /* does the current rectangle intersect with the update
- rectangle? If so, draw it, otherwise, don't */
- if (intersectRect)
- {
- success = SetDIBitsToDevice(hDC, x, y,
- lpBi->bmiHeader.biWidth,
- lpBi->bmiHeader.biHeight,
- 0,0,
- 0, lpBi->bmiHeader.biHeight,
- lpBits, lpBi,
- DIB_RGB_COLORS);
- }
- }
- }
- }
-
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoCreatePaletteFromBitMap() */
- /* */
- /* */
- /* Builds a palette from a given bitmap */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- HPALETTE DoCreatePaletteFromBitMap( HMODULE appInstance,
- WORD bitMapID)
- {
- HANDLE hBitMap;
- HPALETTE hPalette = NULL;
-
-
- hBitMap = LoadResource(appInstance,
- FindResource(appInstance, MAKEINTRESOURCE(bitMapID), RT_BITMAP) );
- if (hBitMap != NULL)
- {
- LPBITMAPINFO lpBi;
- HANDLE hPal;
- LPLOGPALETTE lpPal;
- int i, nColorData;
-
- lpBi = (LPBITMAPINFO)LockResource(hBitMap);
-
- if (lpBi->bmiHeader.biClrUsed != 0)
- {
- nColorData = lpBi->bmiHeader.biClrUsed;
- }
- else
- {
- switch( lpBi->bmiHeader.biBitCount)
- {
- case 1 :
- nColorData = 2;
- break;
-
- case 4 :
- nColorData = 16;
- break;
-
- case 8 :
- nColorData = 256;
- break;
-
- case 24 :
- case 32 :
- nColorData = 0;
- break;
- }
- }
-
- hPal = GlobalAlloc( GHND, sizeof (LOGPALETTE) + (nColorData * sizeof (PALETTEENTRY)) );
- lpPal = (LPLOGPALETTE)GlobalLock(hPal);
-
- lpPal->palVersion = 0x300;
- lpPal->palNumEntries = nColorData;
-
- for (i = 0; i < nColorData; i++)
- {
- lpPal->palPalEntry[i].peRed = lpBi->bmiColors[i].rgbRed;
- lpPal->palPalEntry[i].peGreen = lpBi->bmiColors[i].rgbGreen;
- lpPal->palPalEntry[i].peBlue = lpBi->bmiColors[i].rgbBlue;
-
- }
-
- hPalette = CreatePalette( lpPal );
-
- GlobalUnlock(hPal);
- GlobalFree(hPal);
-
- }
-
- return hPalette;
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoEraseRect() */
- /* */
- /* */
- /* Code to erase a given windows rectangle */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void DoEraseRect(HDC hDC,
- RECT *theRect)
- {
- if (hDC != NULL)
- {
- HBRUSH aBrush;
-
- /* erase rect. for string before redraw */
- aBrush = CreateSolidBrush(RGB(255,255,255));
- if (aBrush != NULL)
- {
- FillRect(hDC, theRect, aBrush);
- DeleteObject(aBrush);
- }
-
- }
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* GetLineHeight() */
- /* */
- /* */
- /* Returns the line height for a given device context */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- int GetLineHeight(HDC hDC)
- {
- TEXTMETRIC tm;
-
- GetTextMetrics(hDC, &tm);
- return(tm.tmExternalLeading + tm.tmHeight);
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DrawHelpMessage() */
- /* */
- /* */
- /* Draws our help text in a window */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void DrawHelpMessage( HDC hDC,
- HWND hwnd)
- {
-
- if (hDC != NULL)
- {
- RECT clientRect, targetRect;
- char helpText[100] = "Press <enter> to advance to next movie frame";
- TEXTMETRIC tm;
- int nLineHeight, strWidth;
-
- GetClientRect(hwnd, &clientRect);
- GetTextMetrics(hDC, &tm);
- nLineHeight = tm.tmExternalLeading + tm.tmHeight;
-
- strWidth = strlen( (LPCTSTR)&helpText ) * tm.tmAveCharWidth;
- SetRect(&targetRect, clientRect.left + ((RECT_WIDTH(clientRect) - strWidth)/2),
- clientRect.bottom - nLineHeight,
- clientRect.left + ((RECT_WIDTH(clientRect) - strWidth)/2) + strWidth,
- clientRect.bottom);
- DoEraseRect(hDC, &targetRect);
-
- /* draw help message */
- DrawText(hDC, (LPCTSTR)&helpText, -1, &targetRect, DT_CENTER);
- }
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoCreateDIBSection() */
- /* */
- /* */
- /* Creates a device independent bitmap using CreateDIBSection */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- HBITMAP DoCreateDIBSection( HDC dc,
- LPRGBQUAD srcRgbQuadArray, /* if (depth > 8), this param ignored */
- WORD depth,
- LONG width,
- LONG height
- )
- {
- UINT usage;
- LPTSTR bits = NULL;
-
- // a struct large enough to hold the largest bitmapinfo ...
- struct BITMAPINFO_256
- {
- BITMAPINFOHEADER bmiHeader;
- long bmiColors[256];
- };
- typedef struct BITMAPINFO_256 BITMAPINFO_256;
-
- BITMAPINFO_256 bmi;
-
-
- memset(&bmi, 0, sizeof(bmi));
-
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = width;
- /* important!!! - we specify a top-down DIB (by passing a negative height value)
- with origin in the upper left, otherwise our movie image will show up as inverted */
- bmi.bmiHeader.biHeight = -1 * height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = depth;
- bmi.bmiHeader.biSizeImage = 0;
- bmi.bmiHeader.biClrUsed = 0;
- bmi.bmiHeader.biClrImportant = 0;
-
-
- switch ( depth )
- {
- case 4:
- case 8:
- {
- long num_colors = (1 << depth),
- i;
- LPRGBQUAD lpQuadDest, lpQuadSource;
-
-
- bmi.bmiHeader.biCompression = BI_RGB;
- usage = DIB_RGB_COLORS;
-
- lpQuadSource = srcRgbQuadArray;
-
- for (i=0; i<num_colors; i++)
- {
- lpQuadDest = (LPRGBQUAD)&bmi.bmiColors[i];
-
- lpQuadDest->rgbBlue = lpQuadSource->rgbBlue;
- lpQuadDest->rgbRed = lpQuadSource->rgbRed;
- lpQuadDest->rgbGreen = lpQuadSource->rgbGreen;
- lpQuadDest->rgbReserved = lpQuadSource->rgbReserved;
-
- ++lpQuadSource;
- }
- }
- break;
-
- case 16:
- case 24:
- case 32:
- {
- bmi.bmiHeader.biCompression = BI_RGB;
- usage = DIB_RGB_COLORS;
-
- bmi.bmiColors[0] = 0;
- bmi.bmiColors[1] = 0;
- bmi.bmiColors[2] = 0;
- }
- break;
-
- default:
- break;
- }
-
- return CreateDIBSection(dc, (BITMAPINFO *) &bmi, usage, &bits, NULL, 0);
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* GetDCBitDepth() */
- /* */
- /* */
- /* Returns the bit depth of a device context */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- WORD GetDCBitDepth(HDC hDC)
- {
- return(GetDeviceCaps( hDC, BITSPIXEL));
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* GetBitDepthOfBitmap() */
- /* */
- /* */
- /* Returns the bit depth of a bitmap */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- WORD GetBitDepthOfBitmap(HMODULE appInstance, /* application instance */
- WORD bitMapID /* resource ID of bit map */
- )
- {
- HBITMAP hBitMap;
-
- hBitMap = LoadResource(appInstance, FindResource(appInstance, MAKEINTRESOURCE(bitMapID), RT_BITMAP) );
- if (hBitMap != NULL)
- {
- LPBITMAPINFO lpBi;
-
- lpBi = (LPBITMAPINFO)LockResource(hBitMap);
-
- return (lpBi->bmiHeader.biBitCount);
- }
- else
- {
- return 0;
- }
-
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* GetRBGColorsFromBitmap() */
- /* */
- /* */
- /* Returns the RGBQUAD array for a bitmap */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void GetRBGColorsFromBitmap(HDC hDC,
- HANDLE hInst,
- WORD bitMapID,
- LPRGBQUAD *srcRgbQuadArray, /* on return, a pointer to a rgbquad
- structure for this bitmap */
- HPALETTE *hPalette) /* if bitmap bit depth <= 8, a custom palette
- for the bitmap will be returned here */
- {
- WORD bitDepthDC, bitDepthBITMAP;
- LPBITMAPINFO srcBITMAPINFO;
- HANDLE hBitMapTemp;
-
- bitDepthDC = GetDCBitDepth(hDC);
- bitDepthBITMAP = GetBitDepthOfBitmap(hInst, /* application instance */
- bitMapID /* resource ID of bit map */
- );
- srcBITMAPINFO = NULL;
- *srcRgbQuadArray = NULL;
- *hPalette = NULL;
-
- /* does the device context have a bit depth <= 8? */
- if (bitDepthDC <= 8)
- {
- /* does our bitmap have a depth <= 8? */
- if (bitDepthBITMAP <= 8)
- {
- /* create custom palette for use with this bitmap */
- *hPalette = DoCreatePaletteFromBitMap(hInst, bitMapID);
-
- /* get color data to use when calling CreateDIBSection */
- hBitMapTemp = LoadResource(hInst,
- FindResource(hInst, MAKEINTRESOURCE(bitMapID),
- RT_BITMAP) );
- if (hBitMapTemp != NULL)
- {
- /* get bitmapinfo data */
- srcBITMAPINFO = (LPBITMAPINFO)LockResource(hBitMapTemp);
- /* get pointer to rgbquad array for this bitmap */
- *srcRgbQuadArray = &srcBITMAPINFO->bmiColors[0];
- }
- }
- }
-
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoCreateMemoryDC() */
- /* */
- /* */
- /* Creates a memory device context */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- HDC DoCreateMemoryDC(HWND hwnd)
- {
- HDC hMemDC, hDC;
-
- hDC = GetDC(hwnd);
- if (hDC)
- {
- hMemDC = CreateCompatibleDC(hDC);
- SetMapMode(hMemDC, GetMapMode(hDC));
- ReleaseDC(hwnd, hDC);
-
- return hMemDC;
- }
-
- return NULL;
- }
-
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* UseCustomPalette() */
- /* */
- /* */
- /* Selects/Realizes a logical palette */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- HPALETTE UseCustomPalette(HDC hDC, HPALETTE newPalette)
- {
- HPALETTE previousPalette;
- UINT nEntries;
-
- /* use a custom palette if need be */
- if (newPalette)
- {
- previousPalette = SelectPalette(hDC, newPalette, FALSE);
- nEntries = RealizePalette(hDC);
- }
-
- return previousPalette;
- }
-
- /* ---------------------------------------------------------------- */
- /* */
- /* DoDrawFrameInfo() */
- /* */
- /* */
- /* Draws our help text messages into a window */
- /* */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void DoDrawFrameInfo(HDC hMemDC,
- HWND hwnd,
- Rect *movieBounds,
- TimeValue theTime)
- {
- RECT destRect;
- int nLineHeight;
- Str255 theString;
- char frameText[25] = "Frame ";
- Rect centeredRect;
-
-
- nLineHeight = GetLineHeight(hMemDC);
-
- CenterMovieRectInWindow(hwnd, /* window where we are placing the image */
- (movieBounds->right - movieBounds->left),
- (movieBounds->bottom - movieBounds->top), /* width, height, of the movie */
- ¢eredRect /* on output, a Mac Rect centered in the window */
- );
- SetRect(&destRect, (int)centeredRect.left - nLineHeight,
- (int)centeredRect.top - nLineHeight /*- menuSize*/,
- (int)centeredRect.right + nLineHeight,
- (int)centeredRect.bottom + nLineHeight /*- menuSize*/);
- DoEraseRect(hMemDC, &destRect);
-
- SetRect(&destRect, (int)centeredRect.left,
- (int)centeredRect.bottom /*- menuSize*/,
- (int)centeredRect.right,
- (int)centeredRect.bottom + nLineHeight /*- menuSize*/);
- DoEraseRect(hMemDC, &destRect);
-
- /* draw new frame # */
- NumToString((long)theTime, theString);
- p2cstr(theString);
- lstrcat((LPSTR)frameText, (LPCSTR)&theString);
- DrawText(hMemDC, (LPCTSTR)&frameText, -1, &destRect, DT_CENTER);
-
- }
-
-
- /* ---------------------------------------------------------------- */
- /* */
- /* CenterMovieRectInWindow() */
- /* */
- /* */
- /* Given height/width values for a movie, returns a Mac rect */
- /* for the movie centered in a window */
- /* */
- /* */
- /* ---------------------------------------------------------------- */
-
- void CenterMovieRectInWindow(HWND hwnd, /* window where we are placing the image */
- int movWidth, int movHeight, /* width, height, of the movie */
- Rect *centeredRect /* on output, a Mac Rect centered in the window */
- )
- {
- RECT clientRect;
- int availSpace;
- BOOL success;
-
- success = GetClientRect(hwnd, // handle of window
- &clientRect// address of structure for client coordinates
- );
-
- availSpace = RECT_WIDTH(clientRect) - movWidth;
- if (availSpace < 0)
- {
- /* movie is bigger than client space? */
- }
- centeredRect->left = clientRect.left + availSpace/2;
-
- availSpace = RECT_HEIGHT(clientRect) - movHeight;
- if (availSpace < 0)
- {
- /* movie is bigger than client space? */
- }
- centeredRect->top = clientRect.top + availSpace/2;
- centeredRect->right = centeredRect->left + movWidth;
- centeredRect->bottom = centeredRect->top + movHeight;
-
- }
-